package com.gopay.scheduler.service.transsolutionordersnap.impl;

import com.gopay.common.constants.trans.OrderType;
import com.gopay.common.core.dic.dao.TransSolutionOrderSnapDao;
import com.gopay.common.core.dic.dao.TransSolutionOrderSnapReadDao;
import com.gopay.common.core.dic.manager.CpsTransInfoQueryManager;
import com.gopay.common.cps.dao.solution.CpsAcctProdMastQueryDAO;
import com.gopay.common.domain.acps.AcctProd;
import com.gopay.common.domain.cps.CpsAcctProdMast;
import com.gopay.common.domain.cps.CpsTransInfo;
import com.gopay.common.domain.solution.TransSolutionOrderSnap;
import com.gopay.remote.solution.SolutionManageRemoteService;
import com.gopay.remote.solution.vo.*;
import com.gopay.scheduler.common.AcctProdTransRelSolution;
import com.gopay.scheduler.service.transsolutionordersnap.TransSolutionOrderSnapService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * CLASSNAME:TransSolutionOrderSnapServiceImpl
 * Description:交易方案排序业务实现类
 * DATE:2018/2/1/001
 * AUTHER:PANSHICHAO
 * www.gopay.com.cn Inc.All rights reserved.
 */
@Service("transSolutionOrderSnapService")
public class TransSolutionOrderSnapServiceImpl implements TransSolutionOrderSnapService {

    @Resource(name = "solutionManageService")
    private SolutionManageRemoteService solutionManageService;
    @Resource(name = "solutionOrderSnapDao")
    private TransSolutionOrderSnapDao transSolutionOrderSnapDao;
    @Resource(name = "solutionOrderSnapReadDao")
    private TransSolutionOrderSnapReadDao transSolutionOrderSnapReadDao;
    @Resource(name = "cpsTransInfoQueryManager")
    private CpsTransInfoQueryManager cpsTransInfoQueryManager;
    @Resource(name = "cpsAcctProdMastQueryDAO")
    private CpsAcctProdMastQueryDAO cpsAcctProdMastQueryDAO;

    private Map<String, CpsAcctProdMast> acctProdMasts = new HashMap<String, CpsAcctProdMast>();
    private Map<String, CpsTransInfo> transInfos = new HashMap<String, CpsTransInfo>();
    private final Logger logger = LoggerFactory.getLogger(TransSolutionOrderSnapServiceImpl.class);

    @PreDestroy
    public void destory() {
        logger.error("destory……");
        transInfos = null;
        acctProdMasts = null;
    }

    /**
     *
     * @param intTxnCd
     * @return
     */
    public boolean containsIntTxnCd(String intTxnCd) {
        if (!transInfos.containsKey(intTxnCd)) {
            synchronized (transInfos) {
                if (!transInfos.containsKey(intTxnCd)) {
                    CpsTransInfo i = cpsTransInfoQueryManager.get(intTxnCd);
                    if (i != null) {
                        transInfos.put(intTxnCd, i);
                    }
                }
            }
        }
        return transInfos.containsKey(intTxnCd);
    }

    /**
     *
     * @param gopayIntTxnCd
     * @return
     */
    private String getGopayIntTxnName(String gopayIntTxnCd) {
        return containsIntTxnCd(gopayIntTxnCd) ? transInfos.get(gopayIntTxnCd)
                .getTransName() : gopayIntTxnCd;
    }

    /**
     *
     * @param prodCode
     * @return
     */
    private boolean containsProdCode(String prodCode) {
        if (!acctProdMasts.containsKey(prodCode)) {
            synchronized (acctProdMasts) {
                if (!acctProdMasts.containsKey(prodCode)) {
                    CpsAcctProdMast m = cpsAcctProdMastQueryDAO.find(
                            CpsAcctProdMast.class, prodCode);
                    if (m != null) {
                        acctProdMasts.put(prodCode, m);
                    }
                }
            }
        }
        return acctProdMasts.containsKey(prodCode);
    }

    /**
     *
     * @param prodCode
     * @return
     */
    private String getProdName(String prodCode) {
        return containsProdCode(prodCode) ? acctProdMasts.get(prodCode)
                .getProdName() : prodCode;
    }


    /**
     *
     */
    private void initAcctProdMasts() {
        synchronized (acctProdMasts) {

            logger.error("init: acctProds……");

            Map<String, CpsAcctProdMast> temp = new HashMap<String, CpsAcctProdMast>();
            List<CpsAcctProdMast> list = cpsAcctProdMastQueryDAO
                    .findAll(CpsAcctProdMast.class);

            for (int i = 0, size = list == null ? 0 : list.size(); i < size; i++) {
                CpsAcctProdMast mast = list.get(i);
                if (mast != null) {
                    String prodCode = mast.getProdCode();
                    if (StringUtils.equals(AcctProd.INTR.toString(), prodCode)) {
                        // 内部账户此处不使用
                        continue;
                    }
                    temp.put(prodCode, mast);
                }
            }
            acctProdMasts = temp;
        }
    }

    /**
     *
     */
    private void initTransInfos() {
        synchronized (transInfos) {

            logger.info("init: transInfo……");

            Map<String, CpsTransInfo> temp = new HashMap<String, CpsTransInfo>();
            List<CpsTransInfo> list = cpsTransInfoQueryManager.getAll();

            for (int i = 0, size = list == null ? 0 : list.size(); i < size; i++) {
                CpsTransInfo info = list.get(i);
                if (info != null) {
                    if (StringUtils.equals(OrderType.ORDER_TYPE_04.toString(),
                            info.getOrderType())) {
                        // 管理类交易此处不使用
                        continue;
                    }
                    temp.put(info.getGopayIntTxnCd(), info);
                }
            }
            transInfos = temp;
        }
    }
    public Map<String, CpsAcctProdMast> getAcctProdMasts() {
        initAcctProdMasts();
        return acctProdMasts;
    }

    public Map<String, CpsTransInfo> getTransInfo() {
        initTransInfos();
        return transInfos;
    }

    @Override
    public List<AcctProdTransRelSolution> findAllAPTransRelSolution(){

        List<AcctProdTransRelSolution> transRels = new ArrayList<AcctProdTransRelSolution>();

        List<SsApSolution> apTransRel = solutionManageService.findAllAPTransSolution();
        if (null == apTransRel || apTransRel.isEmpty()) {
            return transRels;
        }

        for (SsApSolution s : apTransRel) {

            if (null == s) {
                continue;
            }

            Map<String, Integer> map = new HashMap<String, Integer>();

            SsTranBasicSolution solBasic = solutionManageService.findTranBasicSoluByProdCode(s.getProdCode());
            if (null != solBasic && null != solBasic.getDtls() && !solBasic.getDtls().isEmpty()) {
                List<TranBasicDtlInfo> basicDtls = solBasic.getDtls();
                for (TranBasicDtlInfo basicDtl : basicDtls) {
                    map.put(basicDtl.getGopayIntTxnCd(), Integer.valueOf(basicDtl.getIsEnable()));
                }
            }

            List<SolutionDtlInfo> dtls = s.getSolutionDtls();
            if (null != dtls && !dtls.isEmpty()) {
                for (SolutionDtlInfo dtl : dtls) {
                    TransDtlInfo info = (TransDtlInfo) dtl;
                    int isEnable = -1;
                    if (map.containsKey(info.getGopayIntTxnCd())) {
                        Integer isEnableInt = map.get(info.getGopayIntTxnCd());
                        isEnable = isEnableInt.intValue();
                    }
                    transRels.add(initAcctProdTransRelSulotion(info.getGopayIntTxnCd(), s.getProdCode(), isEnable));
                }
            }
        }
        if (transRels != null && transRels.size() > 0) {
            for (int i = 0; i < transRels.size(); i++) {
                if( ("PPTA").equals(transRels.get(i).getProdCode())){
                    transRels.remove(i);
                }
                if( ("PPEA").equals(transRels.get(i).getProdCode())){
                    transRels.remove(i);
                }
                if( ("PPRA").equals(transRels.get(i).getProdCode())){
                    transRels.remove(i);
                }
                if( ("SUBCLOUD").equals(transRels.get(i).getProdCode())){
                    transRels.remove(i);
                }
            }
        }
        return transRels;
    }

    private AcctProdTransRelSolution initAcctProdTransRelSulotion(String intTxnCd, String prodCode, int tranPri) {
        AcctProdTransRelSolution rel = new AcctProdTransRelSolution();
        rel.setIntTxnCd(intTxnCd);
        rel.setIntTxnCdName(getGopayIntTxnName(intTxnCd));
        rel.setProdCode(prodCode);
        rel.setProdCodeName(getProdName(prodCode));
        if(1 == tranPri){
            rel.setTranPri("开通");
        }else if(0 == tranPri){
            rel.setTranPri("关闭");
        }else{
            rel.setTranPri("未初始化");
        }
        return rel;
    }

    @Override
    public Integer findAllTransSolutionOrderSnapCount() {
        String hql = "select count(*) from TransSolutionOrderSnap";
        return transSolutionOrderSnapReadDao.findCountByHql(hql,null);
    }

    @Override
    public List<TransSolutionOrderSnap> findAllTransSolutionOrderSnapInfo() {
        String hql = "from TransSolutionOrderSnap";
        return transSolutionOrderSnapReadDao.findByHql(hql,null);
    }

    @Override
    public void saveTransSolutionOrderSnapInfo(TransSolutionOrderSnap transSolutionOrderSnap) {
        transSolutionOrderSnapDao.save(transSolutionOrderSnap);
    }

    @Override
    public Integer getLastOrderByNum(String prodCode) {
        String hql = "from TransSolutionOrderSnap where prodCode = :prodCode order by orderByNum desc";
        Map<String,Object> param = new HashMap<String,Object>(1);
        param.put("prodCode",prodCode);
        List<TransSolutionOrderSnap> orderSnapList = transSolutionOrderSnapReadDao.findByHql(hql,param);
        return orderSnapList.size() == 0? 0:orderSnapList.get(0).getOrderByNum();
    }

    @Override
    public TransSolutionOrderSnap getAcctProdTransRelSolutionByTransCodeAndProdCode(String transCode, String prodCode) {
        String hql = "from TransSolutionOrderSnap where transCode = :transCode and prodCode = :prodCode";
        Map<String,Object> param = new HashMap<String,Object>(2);
        param.put("transCode",transCode);
        param.put("prodCode",prodCode);
        List<TransSolutionOrderSnap> orderSnapList = transSolutionOrderSnapReadDao.findByHql(hql,param);
        if(orderSnapList!=null&& orderSnapList.size() != 0){
            return orderSnapList.get(0);
        }
        return null;
    }

    @Override
    public TransSolutionOrderSnap getTransSolutionOrderSnapInfoByTransCodeAndProdCodeAndTranPriv(String transCode, String prodCode, String tranPriv) {
        String hql = "from TransSolutionOrderSnap where transCode = :transCode and prodCode = :prodCode and transAuthority = :transPriv";
        Map<String,Object> param = new HashMap<String,Object>(3);
        param.put("transCode",transCode);
        param.put("prodCode",prodCode);
        param.put("transPriv",tranPriv);
        List<TransSolutionOrderSnap> orderSnapList = transSolutionOrderSnapReadDao.findByHql(hql,param);
        if(orderSnapList!=null&& orderSnapList.size() != 0){
            return orderSnapList.get(0);
        }
        return null;
    }
}
